﻿#include "single_tcpserver.h"
#include "log.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>      
#include <arpa/inet.h>  
#include <string.h>  
#include <stdlib.h>
#include <unistd.h>   

#define IEC104_PORT		2404

struct SingleTcpServer
{
    int srvd;
    int clid;

};

/*返回值：<0:错误码；>=0 服务端套接字*/
static int TcpServerCreate(const char* ip, unsigned short port, int num)
{
    int srvd = -1;
    struct sockaddr_in srv_addr;
    int ret;
    int optval;

    srvd = socket(PF_INET, SOCK_STREAM, 0);
    if(srvd < 0)
    {
        goto FAIL;
    }

    optval = 1;
    ret = setsockopt(srvd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    if(ret < 0)
    {
        //do-nothing
    }

    memset(&srv_addr, 0, sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = inet_addr(ip);
    srv_addr.sin_port = htons(port);
    ret = bind(srvd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
    if(ret < 0)
    {
        goto FAIL;
    }

    ret = listen(srvd, num);
    if(ret < 0)
    {
        goto FAIL;
    }

    return srvd;
    FAIL:
    if(srvd >= 0) close(srvd);
    return -1;
}

/*返回值：<0:错误码；>=0 客户端套接字*/
static int TcpServerAccept(int srvd)
{
    int clid;
    
    //LogDebug("accept...");
    clid = accept(srvd, NULL, NULL);
    //LogDebug("accept clid=%d", clid);

    return clid;
}

SingleTcpServer_T* SingleTcpServer_Create()
{
    SingleTcpServer_T* self = (SingleTcpServer_T *)malloc(sizeof(*self));
    self->srvd = TcpServerCreate("0.0.0.0", IEC104_PORT, 1);
    self->clid = -1;

    return self;

}

void SingleTcpServer_Destroy(SingleTcpServer_T* self)
{
    if(self->srvd >= 0) close(self->srvd);
    if(self->clid >= 0) close(self->clid);

    free(self);
}
 
/*最多读len个字节的数据。返回值：<0:错误码；[0,len]:正确 */
int SingleTcpServer_Read(SingleTcpServer_T* self, char* buf, int len)
{
    if(self->clid < 0) return -ENOTCONN;

    len = recv(self->clid, buf, len, 0);
    if(len == 0) return -ECONNRESET; //对端关闭了连接
    else if(len > 0) return len;
    else return -errno;
}

/*最多写len个字节的数据。返回值：<0:错误码；[0,len]:正确*/
int SingleTcpServer_Write(SingleTcpServer_T* self, const char* buf, int len)
{
    if(self->clid < 0) return -ENOTCONN;

    len = send(self->clid, buf, len, 0);

    return len;
}

/*发生错误后用来重置*/
int SingleTcpServer_Reset(SingleTcpServer_T* self)
{
    if(self->clid >= 0) close(self->clid);
    
    self->clid = TcpServerAccept(self->srvd);
    
    return self->clid;
}
